﻿<div>
    <MDataTable Headers="@_headers"
                Items="@_desserts"
                Page="@_page"
                ItemsPerPage="@_itemsPerPage"
                OnOptionsUpdate="@HandleOnOptionsUpdate"
                ServerItemsLength="@_total"
                Loading="_loading"
                Class="elevation-1">
    </MDataTable>
</div>

@code {

    private static readonly IEnumerable<Dessert> AllDesserts = new List<Dessert>
    {
        new Dessert(Name: "Frozen Yogurt", Calories: 159, Fat: 6.0, Carbs: 24, Protein: 4.0, Iron: "1%"),
        new Dessert(Name: "Ice cream sandwich", Calories: 237, Fat: 9.0, Carbs: 37, Protein: 4.3, Iron: "1%"),
        new Dessert(Name: "Eclair", Calories: 262, Fat: 16.0, Carbs: 23, Protein: 6.0, Iron: "7%"),
        new Dessert(Name: "Cupcake", Calories: 305, Fat: 3.7, Carbs: 67, Protein: 4.3, Iron: "8%"),
        new Dessert(Name: "Gingerbread", Calories: 356, Fat: 16.0, Carbs: 49, Protein: 3.9, Iron: "16%"),
        new Dessert(Name: "Jelly bean", Calories: 375, Fat: 0.0, Carbs: 94, Protein: 0.0, Iron: "0%"),
        new Dessert(Name: "Lollipop", Calories: 392, Fat: 0.2, Carbs: 98, Protein: 0, Iron: "2%"),
        new Dessert(Name: "Honeycomb", Calories: 408, Fat: 3.2, Carbs: 87, Protein: 6.5, Iron: "45%"),
        new Dessert(Name: "Donut", Calories: 452, Fat: 25.0, Carbs: 51, Protein: 4.9, Iron: "22%"),
        new Dessert(Name: "KitKat", Calories: 518, Fat: 26.0, Carbs: 65, Protein: 7, Iron: "6%"),
        new Dessert(Name: "Marshmallow", Calories: 318, Fat: 0, Carbs: 81, Protein: 2, Iron: "20%"),
        new Dessert(Name: "Nougat", Calories: 360, Fat: 19.0, Carbs: 9, Protein: 37, Iron: "0%"),
        new Dessert(Name: "Oreo", Calories: 437, Fat: 18.0, Carbs: 63, Protein: 4, Iron: "50%"),
        new Dessert(Name: "Apple pie", Calories: 237, Fat: 2.0, Carbs: 65, Protein: 1, Iron: "0%"),
        new Dessert(Name: "Cheesecake", Calories: 237, Fat: 2.0, Carbs: 65, Protein: 1, Iron: "0%"),
        new Dessert(Name: "Cinnamon roll", Calories: 237, Fat: 2.0, Carbs: 65, Protein: 1, Iron: "0%"),
    };

    private int _total;
    private IEnumerable<Dessert> _desserts = new List<Dessert>();
    private bool _loading = true;
    private int _itemsPerPage = 5;
    private int _page = 1;
    private DataOptions _options = new(1, 5);

    private List<DataTableHeader<Dessert>> _headers = new List<DataTableHeader<Dessert>>
    {
        new()
        {
            Text = "Dessert (100g serving)",
            Align = DataTableHeaderAlign.Start,
            Sortable = false,
            Value = nameof(Dessert.Name)
        },
        new() { Text = "Calories", Value = nameof(Dessert.Calories) },
        new() { Text = "Fat (g)", Value = nameof(Dessert.Fat) },
        new() { Text = "Carbs (g)", Value = nameof(Dessert.Carbs) },
        new() { Text = "Protein (g)", Value = nameof(Dessert.Protein) },
        new() { Text = "Iron (%)", Value = nameof(Dessert.Iron) }
    };

    private async Task HandleOnOptionsUpdate(DataOptions options)
    {
        _options = options;
        await GetDataFromApi();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await GetDataFromApi();
            StateHasChanged();
        }
    }

    private async Task GetDataFromApi()
    {
        _loading = true;
        (_desserts, _total) = await FakeApiCallAsync();
        _loading = false;
    }

    private async Task<(IEnumerable<Dessert> items, int total)> FakeApiCallAsync()
    {
        var sortBy = _options.SortBy;
        var sortDesc = _options.SortDesc;
        _page = _options.Page;
        _itemsPerPage = _options.ItemsPerPage;

        var items = AllDesserts.AsQueryable();
        var total = items.Count();

        if (sortBy.Count == 1 && sortDesc.Count == 1)
        {
            var header = _headers.Find(header => header.Value == sortBy[0]);
            var selector = header.ItemValue.Factory;

            if (!sortDesc[0])
            {
                items = items.OrderBy(selector).AsQueryable();
            }
            else
            {
                items = items.OrderByDescending(selector).AsQueryable();
            }
        }

        if (_itemsPerPage > 0)
        {
            items = items.Skip((_page - 1) * _itemsPerPage).Take(_itemsPerPage);
        }

        await Task.Delay(1000);
        return (items, total);
    }

    private record Dessert(string? Name, int Calories, double Fat, int Carbs, double Protein, string? Iron);

}